package javase.jmx.remote;


import javase.jmx.notifications.HelloMBean;

import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.NotificationFilter;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

/* 
 * 
 * In order to run this example 
 * javase.jmx.notifications.Agent should be launched with parameters 
 * -Dcom.sun.management.jmxremote.port=9999 
 * -Dcom.sun.management.jmxremote.authenticate=false 
 * -Dcom.sun.management.jmxremote.ssl=false
 * 
 */
public class RemoteMBeanClient {

	public static void main(String[] args) throws Exception {
		testRemoteAccessToMBean();
	}

	private static void testRemoteAccessToMBean() throws Exception {
        echo("Create an RMI connector client and connect it to the RMI connector server");
        
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxConnector = JMXConnectorFactory.connect(url, null);
        
        emtyLine();
        echo("Get an MBeanServerConnection");
        MBeanServerConnection messageBeanServerConnection = jmxConnector.getMBeanServerConnection();

        performManagementActionsOnMBean(messageBeanServerConnection);

        jmxConnector.close();
	}

	private static void performManagementActionsOnMBean(MBeanServerConnection messageBeanServerConnection) throws Exception {
		echo("Perform operations on Hello MBean");
		emtyLine();

		HelloMBean mbeanProxy = getMBeanProxy(messageBeanServerConnection);

        changeProperty(mbeanProxy);

        callMethods(mbeanProxy);
	}

	private static void callMethods(HelloMBean mbeanProxy) {
		emtyLine();
		echo("Invoke sayHello() in Hello MBean...");
        mbeanProxy.sayHello();
        echo("Invoke add(2, 3) in Hello MBean...");
        echo("add(2, 3) = " + mbeanProxy.add(2, 3));
	}

	private static void changeProperty(HelloMBean mbeanProxy) {
		emtyLine();
		echo("CacheSize = " + mbeanProxy.getCacheSize());
        mbeanProxy.setCacheSize(150);
        emtyLine();
        echo("Waiting for notification...");
        sleep(2000);
        emtyLine();
        echo("CacheSize = " + mbeanProxy.getCacheSize());
	}

	private static HelloMBean getMBeanProxy(MBeanServerConnection messageBeanServerConnection) throws Exception {
		ObjectName mbeanName = new ObjectName("javase.jmx.notifications:type=Hello");
        echo("Add notification listener...");
        ClientListener listener = new ClientListener();
        NotificationFilter notificationFilter = null;
        Object handback = null;
        messageBeanServerConnection.addNotificationListener(mbeanName, listener, notificationFilter, handback);
        boolean behaveAsNotificationBroadcaster = true;
        HelloMBean mbeanProxy = JMX.newMBeanProxy(messageBeanServerConnection, mbeanName, HelloMBean.class, behaveAsNotificationBroadcaster);
		return mbeanProxy;
	}

	private static void emtyLine() {
		echo("");
	}

    private static void echo(String msg) {
        System.out.println(msg);
    }

    private static void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

